#ifndef AVALON_DIRECTORYENTRY_HPP
#define AVALON_DIRECTORYENTRY_HPP
#include "Avalon/Base/Enumerator.hpp"
#include "Avalon/Serialization/Serialization.hpp"
#include "Avalon/ServiceLocator/ServiceLocator.hpp"

namespace Avalon {
namespace ServiceLocator {

  /*! \class DirectoryEntry
   *  \brief Base class for a Directory or Account.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class DirectoryEntry {
    public:

      /*! \struct TypeDefinition
       *  \brief Enumerates types of DirectoryEntries.
       */
      struct TypeDefinition {
        enum Type {

          //! Account.
          ACCOUNT,

          //! Directory.
          DIRECTORY
        };
      };
      typedef Enumerator<TypeDefinition> Type;

      /*! \struct Tag
       *  \brief Stores the name and id of a DirectoryEntry.
       */
      struct Tag {

        //! The Type.
        Type m_type;

        //! The unique id.
        unsigned int m_id;

        //! The name.
        std::string m_name;

        //! Constructs an empty Tag.
        Tag();

        //! Constructs a Tag.
        /*!
          \param type The Type.
          \param id The id.
          \param name The name.
        */
        Tag(Type type, unsigned int id, const std::string& name);

        //! Tests if this Tag's is less than another.
        /*!
          \param rhs The right-hand side of the operation.
          \return <code>true</code> iff this Tag's id is less than <i>rhs</i>'s
                  id.
        */
        bool operator <(const Tag& rhs) const;

        //! Tests if this Tag identifies the same DirectoryEntry as another.
        /*!
          \param rhs The right-hand side of the operation.
          \return <code>true</code> iff this Tag identifies the same
                  DirectoryEntry as <i>rhs</i>.
        */
        bool operator ==(const Tag& rhs) const;

        private:
          friend class Serialization::DataShuttle;

          void Shuttle(Serialization::DataShuttle* shuttle,
            unsigned int version);
      };

      virtual ~DirectoryEntry();

      //! Returns the Type.
      virtual Type GetType() = 0;

      //! Returns the Tag.
      virtual Tag GetTag() = 0;

    protected:
      friend class Serialization::DataShuttle;

      //! Serializes the contents of this DirectoryEntry.
      /*!
        \param shuttle The DataShuttle to serialize the contents to.
        \param version The class version to serialize.
      */
      virtual void Shuttle(Serialization::DataShuttle* shuttle,
        unsigned int version) = 0;
  };
}
}

#endif // AVALON_DIRECTORYENTRY_HPP
